package com.atguigu.lease.common.handler;

import com.atguigu.lease.common.util.JwtUtil;
import com.atguigu.lease.model.bean.SystemUser;
import io.jsonwebtoken.impl.DefaultClaims;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.HandlerInterceptor;
//拦截器必须注册拦截地址，否则不生效！！！！！
@Component
public class StgyAdminAuthInterceptor implements HandlerInterceptor {
    public static final ThreadLocal<SystemUser> SYSTEM_USER_THREAD_LOCAL = new ThreadLocal<>();
    //handler方法执行前拦截请求  返回true表示放行  false拦截请求
    @Override
    public boolean preHandle(jakarta.servlet.http.HttpServletRequest request,
                             jakarta.servlet.http.HttpServletResponse response,
                             Object handler) throws Exception {
        //判断 如果是客户端的预检请求 直接放行，不能拦截：因为预检请求不会携带jwt token
        if(request.getMethod().toUpperCase().equals(RequestMethod.OPTIONS.name())){
            return true;
        }

        //获取请求报文中的ACCESS_TOKEN 进行校验
        String token = request.getHeader("ACCESS_TOKEN");
        DefaultClaims claims = JwtUtil.parseToken(token);//解析时 如果token解析失败 直接抛出异常，后面的代码不会执行了
        SystemUser systemUser = new SystemUser();
        systemUser.setAvatarUrl(claims.get("avatarUrl", String.class));
        systemUser.setName(claims.get("name", String.class));
        systemUser.setId(Long.parseLong(claims.get("userId", String.class)));
        //设置数据到线程对象的map中：原理(获取线程对象，将set()方法接受到的参数 设置到 线程对象的map中)
        SYSTEM_USER_THREAD_LOCAL.set(systemUser);
        //放行： token存在并且解析成功
        return true;
    }
    //防止内存泄漏：
    //handler方法调用完毕后 才会执行，可以进行收尾操作：删除线程对象缓存的数据
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        SYSTEM_USER_THREAD_LOCAL.remove();
    }
}
